import EventExt from './EventExt';
import { EVENT_KEY_PLAY_AUDIO, IEventAudio, IEventBase } from './EventType';

/**
 * 自定义事件帮助类 -- 简化创建唯一受理类型事件
 * 
 * 比 EventExt 多了类型检查处理；
 * 移除事件监听不需要拓展，直接使用 EventExt;
 */
export default class EventHelper {

    /**
     * 抛出特殊的自定义事件
     * @param type - event type
     * @param arg - Arguments when the event triggered
     */
    static emitEvent<T extends IEventBase>(type: string | number, arg: T): void {
        arg.isEventDone = false;
        EventExt.emit(type, arg);
    }

    /**
     * 注册事件目标的特定事件类型回调。这种类型的事件应该被 `emit` 触发。
     * @param type - A string representing the event type to listen for.
     * @param callback - The callback that will be invoked when the event is dispatched.
     *                              The callback is ignored if it is a duplicate (the callbacks are unique).
     * @param thisArg - The target (this object) to invoke the callback, can be null
     */
    static on<T extends IEventBase>(type: string | number, callback: (p: T) => boolean, thisArg?: any, once?: boolean): void {
        const func = (p: IEventBase) => {
            if (p.isEventDone)
                return;
            p.isEventDone = callback.call(thisArg, p);
        };
        EventExt.on(type, func, thisArg, once);
    }

    /**
     * 播放音效事件简易接口
     * 需配合[AudioComponent]组件使用，由该组件负责具体实现播放及相关处理
     * @param audioName 音效名称
     * @param isVoice 是否是人物语音（处理多语言用）
     */
    static playAudio(audioName: string, isVoice?: boolean): void {
        if (audioName) {
            const p: IEventAudio = { audioName, isVoice };
            EventHelper.emitEvent(EVENT_KEY_PLAY_AUDIO, p);
        }
    }

    /**
     * 播放临时的背景音乐
     * 暂停当前背景音乐，播放指定背景音乐
     * 需配合AudioComp组件使用，由该组件负责具体实现播放及相关处理
     * @param audioName 
     */
    static playBGM(audioName: string): void {
        if (audioName) {
            const p: IEventAudio = { audioName, isBGM: true };
            EventHelper.emitEvent(EVENT_KEY_PLAY_AUDIO, p);
        }
    }

    /**
     * 监听音效事件简易接口
     * 参数详情参考 on 接口
     */
    static onAudio(callback: (p: IEventAudio) => boolean, thisArg?: any, once?: boolean): void {
        EventHelper.on(EVENT_KEY_PLAY_AUDIO, callback, thisArg, once);
    }
}
